﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x0200016A RID: 362
	[Serializable]
	public abstract class IKSolver
	{
		// Token: 0x06000651 RID: 1617 RVA: 0x0001EE20 File Offset: 0x0001D220
		public bool IsValid()
		{
			string empty = string.Empty;
			return this.IsValid(ref empty);
		}

		// Token: 0x06000652 RID: 1618
		public abstract bool IsValid(ref string message);

		// Token: 0x06000653 RID: 1619 RVA: 0x0001EE3C File Offset: 0x0001D23C
		public void Initiate(Transform root)
		{
			if (this.OnPreInitiate != null)
			{
				this.OnPreInitiate();
			}
			if (root == null)
			{
				Debug.LogError("Initiating IKSolver with null root Transform.");
			}
			this.root = root;
			this.initiated = false;
			string empty = string.Empty;
			if (!this.IsValid(ref empty))
			{
				Warning.Log(empty, root, false);
				return;
			}
			this.OnInitiate();
			this.StoreDefaultLocalState();
			this.initiated = true;
			this.firstInitiation = false;
			if (this.OnPostInitiate != null)
			{
				this.OnPostInitiate();
			}
		}

		// Token: 0x06000654 RID: 1620 RVA: 0x0001EED0 File Offset: 0x0001D2D0
		public void Update()
		{
			if (this.OnPreUpdate != null)
			{
				this.OnPreUpdate();
			}
			if (this.firstInitiation)
			{
				this.Initiate(this.root);
			}
			if (!this.initiated)
			{
				return;
			}
			this.OnUpdate();
			if (this.OnPostUpdate != null)
			{
				this.OnPostUpdate();
			}
		}

		// Token: 0x06000655 RID: 1621 RVA: 0x0001EF32 File Offset: 0x0001D332
		public virtual Vector3 GetIKPosition()
		{
			return this.IKPosition;
		}

		// Token: 0x06000656 RID: 1622 RVA: 0x0001EF3A File Offset: 0x0001D33A
		public void SetIKPosition(Vector3 position)
		{
			this.IKPosition = position;
		}

		// Token: 0x06000657 RID: 1623 RVA: 0x0001EF43 File Offset: 0x0001D343
		public float GetIKPositionWeight()
		{
			return this.IKPositionWeight;
		}

		// Token: 0x06000658 RID: 1624 RVA: 0x0001EF4B File Offset: 0x0001D34B
		public void SetIKPositionWeight(float weight)
		{
			this.IKPositionWeight = Mathf.Clamp(weight, 0f, 1f);
		}

		// Token: 0x06000659 RID: 1625 RVA: 0x0001EF63 File Offset: 0x0001D363
		public Transform GetRoot()
		{
			return this.root;
		}

		// Token: 0x17000053 RID: 83
		// (get) Token: 0x0600065A RID: 1626 RVA: 0x0001EF6B File Offset: 0x0001D36B
		// (set) Token: 0x0600065B RID: 1627 RVA: 0x0001EF73 File Offset: 0x0001D373
		public bool initiated { get; private set; }

		// Token: 0x0600065C RID: 1628
		public abstract IKSolver.Point[] GetPoints();

		// Token: 0x0600065D RID: 1629
		public abstract IKSolver.Point GetPoint(Transform transform);

		// Token: 0x0600065E RID: 1630
		public abstract void FixTransforms();

		// Token: 0x0600065F RID: 1631
		public abstract void StoreDefaultLocalState();

		// Token: 0x06000660 RID: 1632
		protected abstract void OnInitiate();

		// Token: 0x06000661 RID: 1633
		protected abstract void OnUpdate();

		// Token: 0x06000662 RID: 1634 RVA: 0x0001EF7C File Offset: 0x0001D37C
		protected void LogWarning(string message)
		{
			Warning.Log(message, this.root, true);
		}

		// Token: 0x06000663 RID: 1635 RVA: 0x0001EF8C File Offset: 0x0001D38C
		public static Transform ContainsDuplicateBone(IKSolver.Bone[] bones)
		{
			for (int i = 0; i < bones.Length; i++)
			{
				for (int j = 0; j < bones.Length; j++)
				{
					if (i != j && bones[i].transform == bones[j].transform)
					{
						return bones[i].transform;
					}
				}
			}
			return null;
		}

		// Token: 0x06000664 RID: 1636 RVA: 0x0001EFEC File Offset: 0x0001D3EC
		public static bool HierarchyIsValid(IKSolver.Bone[] bones)
		{
			for (int i = 1; i < bones.Length; i++)
			{
				if (!Hierarchy.IsAncestor(bones[i].transform, bones[i - 1].transform))
				{
					return false;
				}
			}
			return true;
		}

		// Token: 0x06000665 RID: 1637 RVA: 0x0001F02C File Offset: 0x0001D42C
		protected static float PreSolveBones(ref IKSolver.Bone[] bones)
		{
			float num = 0f;
			for (int i = 0; i < bones.Length; i++)
			{
				bones[i].solverPosition = bones[i].transform.position;
				bones[i].solverRotation = bones[i].transform.rotation;
			}
			for (int j = 0; j < bones.Length; j++)
			{
				if (j < bones.Length - 1)
				{
					bones[j].sqrMag = (bones[j + 1].solverPosition - bones[j].solverPosition).sqrMagnitude;
					bones[j].length = Mathf.Sqrt(bones[j].sqrMag);
					num += bones[j].length;
					bones[j].axis = Quaternion.Inverse(bones[j].solverRotation) * (bones[j + 1].solverPosition - bones[j].solverPosition);
				}
				else
				{
					bones[j].sqrMag = 0f;
					bones[j].length = 0f;
				}
			}
			return num;
		}

		// Token: 0x04000388 RID: 904
		[HideInInspector]
		public Vector3 IKPosition;

		// Token: 0x04000389 RID: 905
		[Tooltip("The positional or the master weight of the solver.")]
		[Range(0f, 1f)]
		public float IKPositionWeight = 1f;

		// Token: 0x0400038B RID: 907
		public IKSolver.UpdateDelegate OnPreInitiate;

		// Token: 0x0400038C RID: 908
		public IKSolver.UpdateDelegate OnPostInitiate;

		// Token: 0x0400038D RID: 909
		public IKSolver.UpdateDelegate OnPreUpdate;

		// Token: 0x0400038E RID: 910
		public IKSolver.UpdateDelegate OnPostUpdate;

		// Token: 0x0400038F RID: 911
		protected bool firstInitiation = true;

		// Token: 0x04000390 RID: 912
		[SerializeField]
		[HideInInspector]
		protected Transform root;

		// Token: 0x0200016B RID: 363
		[Serializable]
		public class Point
		{
			// Token: 0x06000667 RID: 1639 RVA: 0x0001F165 File Offset: 0x0001D565
			public void StoreDefaultLocalState()
			{
				this.defaultLocalPosition = this.transform.localPosition;
				this.defaultLocalRotation = this.transform.localRotation;
			}

			// Token: 0x06000668 RID: 1640 RVA: 0x0001F18C File Offset: 0x0001D58C
			public void FixTransform()
			{
				if (this.transform.localPosition != this.defaultLocalPosition)
				{
					this.transform.localPosition = this.defaultLocalPosition;
				}
				if (this.transform.localRotation != this.defaultLocalRotation)
				{
					this.transform.localRotation = this.defaultLocalRotation;
				}
			}

			// Token: 0x06000669 RID: 1641 RVA: 0x0001F1F1 File Offset: 0x0001D5F1
			public void UpdateSolverPosition()
			{
				this.solverPosition = this.transform.position;
			}

			// Token: 0x0600066A RID: 1642 RVA: 0x0001F204 File Offset: 0x0001D604
			public void UpdateSolverLocalPosition()
			{
				this.solverPosition = this.transform.localPosition;
			}

			// Token: 0x0600066B RID: 1643 RVA: 0x0001F217 File Offset: 0x0001D617
			public void UpdateSolverState()
			{
				this.solverPosition = this.transform.position;
				this.solverRotation = this.transform.rotation;
			}

			// Token: 0x0600066C RID: 1644 RVA: 0x0001F23B File Offset: 0x0001D63B
			public void UpdateSolverLocalState()
			{
				this.solverPosition = this.transform.localPosition;
				this.solverRotation = this.transform.localRotation;
			}

			// Token: 0x04000391 RID: 913
			public Transform transform;

			// Token: 0x04000392 RID: 914
			[Range(0f, 1f)]
			public float weight = 1f;

			// Token: 0x04000393 RID: 915
			public Vector3 solverPosition;

			// Token: 0x04000394 RID: 916
			public Quaternion solverRotation = Quaternion.identity;

			// Token: 0x04000395 RID: 917
			public Vector3 defaultLocalPosition;

			// Token: 0x04000396 RID: 918
			public Quaternion defaultLocalRotation;
		}

		// Token: 0x0200016C RID: 364
		[Serializable]
		public class Bone : IKSolver.Point
		{
			// Token: 0x0600066D RID: 1645 RVA: 0x0001F25F File Offset: 0x0001D65F
			public Bone()
			{
			}

			// Token: 0x0600066E RID: 1646 RVA: 0x0001F27E File Offset: 0x0001D67E
			public Bone(Transform transform)
			{
				this.transform = transform;
			}

			// Token: 0x0600066F RID: 1647 RVA: 0x0001F2A4 File Offset: 0x0001D6A4
			public Bone(Transform transform, float weight)
			{
				this.transform = transform;
				this.weight = weight;
			}

			// Token: 0x17000054 RID: 84
			// (get) Token: 0x06000670 RID: 1648 RVA: 0x0001F2D4 File Offset: 0x0001D6D4
			// (set) Token: 0x06000671 RID: 1649 RVA: 0x0001F328 File Offset: 0x0001D728
			public RotationLimit rotationLimit
			{
				get
				{
					if (!this.isLimited)
					{
						return null;
					}
					if (this._rotationLimit == null)
					{
						this._rotationLimit = this.transform.GetComponent<RotationLimit>();
					}
					this.isLimited = (this._rotationLimit != null);
					return this._rotationLimit;
				}
				set
				{
					this._rotationLimit = value;
					this.isLimited = (value != null);
				}
			}

			// Token: 0x06000672 RID: 1650 RVA: 0x0001F340 File Offset: 0x0001D740
			public void Swing(Vector3 swingTarget, float weight = 1f)
			{
				if (weight <= 0f)
				{
					return;
				}
				Quaternion quaternion = Quaternion.FromToRotation(this.transform.rotation * this.axis, swingTarget - this.transform.position);
				if (weight >= 1f)
				{
					this.transform.rotation = quaternion * this.transform.rotation;
					return;
				}
				this.transform.rotation = Quaternion.Lerp(Quaternion.identity, quaternion, weight) * this.transform.rotation;
			}

			// Token: 0x06000673 RID: 1651 RVA: 0x0001F3D8 File Offset: 0x0001D7D8
			public static void SolverSwing(IKSolver.Bone[] bones, int index, Vector3 swingTarget, float weight = 1f)
			{
				if (weight <= 0f)
				{
					return;
				}
				Quaternion quaternion = Quaternion.FromToRotation(bones[index].solverRotation * bones[index].axis, swingTarget - bones[index].solverPosition);
				if (weight >= 1f)
				{
					for (int i = index; i < bones.Length; i++)
					{
						bones[i].solverRotation = quaternion * bones[i].solverRotation;
					}
					return;
				}
				for (int j = index; j < bones.Length; j++)
				{
					bones[j].solverRotation = Quaternion.Lerp(Quaternion.identity, quaternion, weight) * bones[j].solverRotation;
				}
			}

			// Token: 0x06000674 RID: 1652 RVA: 0x0001F488 File Offset: 0x0001D888
			public void Swing2D(Vector3 swingTarget, float weight = 1f)
			{
				if (weight <= 0f)
				{
					return;
				}
				Vector3 vector = this.transform.rotation * this.axis;
				Vector3 vector2 = swingTarget - this.transform.position;
				float current = Mathf.Atan2(vector.x, vector.y) * 57.29578f;
				float target = Mathf.Atan2(vector2.x, vector2.y) * 57.29578f;
				this.transform.rotation = Quaternion.AngleAxis(Mathf.DeltaAngle(current, target) * weight, Vector3.back) * this.transform.rotation;
			}

			// Token: 0x06000675 RID: 1653 RVA: 0x0001F52C File Offset: 0x0001D92C
			public void SetToSolverPosition()
			{
				this.transform.position = this.solverPosition;
			}

			// Token: 0x04000397 RID: 919
			public float length;

			// Token: 0x04000398 RID: 920
			public float sqrMag;

			// Token: 0x04000399 RID: 921
			public Vector3 axis = -Vector3.right;

			// Token: 0x0400039A RID: 922
			private RotationLimit _rotationLimit;

			// Token: 0x0400039B RID: 923
			private bool isLimited = true;
		}

		// Token: 0x0200016D RID: 365
		[Serializable]
		public class Node : IKSolver.Point
		{
			// Token: 0x06000676 RID: 1654 RVA: 0x0001F53F File Offset: 0x0001D93F
			public Node()
			{
			}

			// Token: 0x06000677 RID: 1655 RVA: 0x0001F547 File Offset: 0x0001D947
			public Node(Transform transform)
			{
				this.transform = transform;
			}

			// Token: 0x06000678 RID: 1656 RVA: 0x0001F556 File Offset: 0x0001D956
			public Node(Transform transform, float weight)
			{
				this.transform = transform;
				this.weight = weight;
			}

			// Token: 0x0400039C RID: 924
			public float length;

			// Token: 0x0400039D RID: 925
			public float effectorPositionWeight;

			// Token: 0x0400039E RID: 926
			public float effectorRotationWeight;

			// Token: 0x0400039F RID: 927
			public Vector3 offset;
		}

		// Token: 0x0200016E RID: 366
		// (Invoke) Token: 0x0600067A RID: 1658
		public delegate void UpdateDelegate();

		// Token: 0x0200016F RID: 367
		// (Invoke) Token: 0x0600067E RID: 1662
		public delegate void IterationDelegate(int i);
	}
}
